﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;

namespace UseEntityJig
{
    public class BreakLineWithNode
    {
        /// <summary>
        /// 自动分割 不需要先选择直线
        /// </summary>
        [CommandMethod("BreakLineUseNode")]
        public void BreakLineUseNode()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                // 提示用户选择截断点
                PromptPointOptions pointOptions = new PromptPointOptions("\n请选择截断点: ");
                PromptPointResult pointResult = ed.GetPoint(pointOptions);

                if (pointResult.Status != PromptStatus.OK)
                    return;

                Point3d breakPoint = pointResult.Value;
                double nodeRadius = 1; // 半径为0.5（直径为1）的圆圈

                // 获取在截断点附近的所有直线
                PromptSelectionResult selectionResult = ed.SelectCrossingWindow(breakPoint - new Vector3d(0.1, 0.1, 0),
                                                                                breakPoint + new Vector3d(0.1, 0.1, 0));

                if (selectionResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n没有找到直线对象。");
                    return;
                }

                // 筛选出最近的直线
                ObjectId closestLineId = ObjectId.Null;
                double minDistance = double.MaxValue;

                foreach (SelectedObject selectedObj in selectionResult.Value)
                {
                    Entity entity = trans.GetObject(selectedObj.ObjectId, OpenMode.ForRead) as Entity;
                    if (entity is Line line)
                    {
                        double distance = line.GetClosestPointTo(breakPoint, false).DistanceTo(breakPoint);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            closestLineId = selectedObj.ObjectId;
                        }
                    }
                }

                if (closestLineId == ObjectId.Null)
                {
                    ed.WriteMessage("\n没有找到符合条件的直线。");
                    return;
                }

                // 获取最近的直线
                Line originalLine = trans.GetObject(closestLineId, OpenMode.ForWrite) as Line;

                // 创建node3圆圈，中心点为截断点
                Circle node3 = new Circle(breakPoint, Vector3d.ZAxis, nodeRadius);
                btr.AppendEntity(node3);
                trans.AddNewlyCreatedDBObject(node3, true);

                // 获取直线的起点和终点
                Point3d startPoint = originalLine.StartPoint;
                Point3d endPoint = originalLine.EndPoint;

                // 计算向量
                Vector3d lineDirection = (endPoint - startPoint).GetNormal();

                // 计算与圆圈相切的点
                Point3d firstTangentPoint = breakPoint - lineDirection * nodeRadius;
                Point3d secondTangentPoint = breakPoint + lineDirection * nodeRadius;

                // 创建两条新的直线段
                Line lineSegment1 = new Line(startPoint, firstTangentPoint);
                Line lineSegment2 = new Line(secondTangentPoint, endPoint);

                // 将新线段添加到块表记录中
                btr.AppendEntity(lineSegment1);
                trans.AddNewlyCreatedDBObject(lineSegment1, true);
                btr.AppendEntity(lineSegment2);
                trans.AddNewlyCreatedDBObject(lineSegment2, true);

                // 删除原来的直线
                originalLine.Erase();

                // 提交事务
                trans.Commit();
            }
        }

        /// <summary>
        /// 分割线型不变
        /// </summary>
        [CommandMethod("BreakLineUseNode2")]
        public void BreakLineUseNode2()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                // 提示用户选择截断点
                PromptPointOptions pointOptions = new PromptPointOptions("\n请选择截断点: ");
                PromptPointResult pointResult = ed.GetPoint(pointOptions);

                if (pointResult.Status != PromptStatus.OK)
                    return;

                Point3d breakPoint = pointResult.Value;
                double nodeRadius = 1; // 半径为1的圆圈

                // 获取在截断点附近的所有直线
                PromptSelectionResult selectionResult = ed.SelectCrossingWindow(breakPoint - new Vector3d(0.1, 0.1, 0),
                                                                                breakPoint + new Vector3d(0.1, 0.1, 0));

                if (selectionResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n没有找到直线对象。");
                    return;
                }

                // 筛选出最近的直线
                ObjectId closestLineId = ObjectId.Null;
                double minDistance = double.MaxValue;

                foreach (SelectedObject selectedObj in selectionResult.Value)
                {
                    Entity entity = trans.GetObject(selectedObj.ObjectId, OpenMode.ForRead) as Entity;
                    if (entity is Line line)
                    {
                        double distance = line.GetClosestPointTo(breakPoint, false).DistanceTo(breakPoint);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            closestLineId = selectedObj.ObjectId;
                        }
                    }
                }

                if (closestLineId == ObjectId.Null)
                {
                    ed.WriteMessage("\n没有找到符合条件的直线。");
                    return;
                }

                // 获取最近的直线
                Line originalLine = trans.GetObject(closestLineId, OpenMode.ForWrite) as Line;

                // 保存原直线的属性
                string lineType = originalLine.Linetype;
                double lineTypeScale = originalLine.LinetypeScale;
                Color color = originalLine.Color;
                string layer = originalLine.Layer;
                LineWeight lineWeight = originalLine.LineWeight;

                // 创建node3圆圈，中心点为截断点
                Circle node3 = new Circle(breakPoint, Vector3d.ZAxis, nodeRadius);
                btr.AppendEntity(node3);
                trans.AddNewlyCreatedDBObject(node3, true);

                // 获取直线的起点和终点
                Point3d startPoint = originalLine.StartPoint;
                Point3d endPoint = originalLine.EndPoint;

                // 计算向量
                Vector3d lineDirection = (endPoint - startPoint).GetNormal();

                // 计算与圆圈相切的点
                Point3d firstTangentPoint = breakPoint - lineDirection * nodeRadius;
                Point3d secondTangentPoint = breakPoint + lineDirection * nodeRadius;

                // 创建两条新的直线段
                Line lineSegment1 = new Line(startPoint, firstTangentPoint);
                Line lineSegment2 = new Line(secondTangentPoint, endPoint);

                // 复制原直线的属性到新直线段
                lineSegment1.Linetype = lineType;
                lineSegment1.LinetypeScale = lineTypeScale;
                lineSegment1.Color = color;
                lineSegment1.Layer = layer;
                lineSegment1.LineWeight = lineWeight;

                lineSegment2.Linetype = lineType;
                lineSegment2.LinetypeScale = lineTypeScale;
                lineSegment2.Color = color;
                lineSegment2.Layer = layer;
                lineSegment2.LineWeight = lineWeight;

                // 将新线段添加到块表记录中
                btr.AppendEntity(lineSegment1);
                trans.AddNewlyCreatedDBObject(lineSegment1, true);
                btr.AppendEntity(lineSegment2);
                trans.AddNewlyCreatedDBObject(lineSegment2, true);

                // 删除原来的直线
                originalLine.Erase();

                // 提交事务
                trans.Commit();
            }
        }

        #region 直线分断 自动标记线段标注Dimension


        [CommandMethod("AddBundleDimension")]
        public void AddBundleDimension()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                // 示例: 用户绘制一条Bundle（直线）
                Line bundleLine = new Line(new Point3d(100, 200, 0), new Point3d(100, 300, 0));

                // 设置直线属性
                bundleLine.Linetype = "ByLayer";
                bundleLine.Color = Color.FromColorIndex(ColorMethod.ByLayer, 256);
                bundleLine.Layer = "0";
                bundleLine.LineWeight = Autodesk.AutoCAD.DatabaseServices.LineWeight.LineWeight050;

                // 添加直线到块表记录
                btr.AppendEntity(bundleLine);
                trans.AddNewlyCreatedDBObject(bundleLine, true);

                // 添加长度标注
                //AddLengthAnnotation(trans, btr, bundleLine);

                trans.Commit();
            }
        }

        #endregion

        #region 直线分断，自动标记MText 作为长度标注
        [CommandMethod("BreakLineUseNode4")]
        public void BreakLineUseNode4()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;

            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord btr = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;

                // 提示用户选择截断点
                PromptPointOptions pointOptions = new PromptPointOptions("\n请选择截断点: ");
                PromptPointResult pointResult = ed.GetPoint(pointOptions);

                if (pointResult.Status != PromptStatus.OK)
                    return;

                Point3d breakPoint = pointResult.Value;
                double nodeRadius = 0.5; // 半径为0.5（直径为1）的圆圈

                // 获取在截断点附近的所有直线
                PromptSelectionResult selectionResult = ed.SelectCrossingWindow(breakPoint - new Vector3d(0.1, 0.1, 0),
                                                                                breakPoint + new Vector3d(0.1, 0.1, 0));

                if (selectionResult.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n没有找到直线对象。");
                    return;
                }

                // 筛选出最近的直线
                ObjectId closestLineId = ObjectId.Null;
                double minDistance = double.MaxValue;

                foreach (SelectedObject selectedObj in selectionResult.Value)
                {
                    Entity entity = trans.GetObject(selectedObj.ObjectId, OpenMode.ForRead) as Entity;
                    if (entity is Line line)
                    {
                        double distance = line.GetClosestPointTo(breakPoint, false).DistanceTo(breakPoint);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            closestLineId = selectedObj.ObjectId;
                        }
                    }
                }

                if (closestLineId == ObjectId.Null)
                {
                    ed.WriteMessage("\n没有找到符合条件的直线。");
                    return;
                }

                // 获取最近的直线
                Line originalLine = trans.GetObject(closestLineId, OpenMode.ForWrite) as Line;

                // 删除原来的长度标注
                RemoveLengthMText(trans, btr, originalLine);

                // 保存原直线的属性
                string lineType = originalLine.Linetype;
                double lineTypeScale = originalLine.LinetypeScale;
                Color color = originalLine.Color;
                string layer = originalLine.Layer;
                LineWeight lineWeight = originalLine.LineWeight;

                // 创建node3圆圈，中心点为截断点
                Circle node3 = new Circle(breakPoint, Vector3d.ZAxis, nodeRadius);
                btr.AppendEntity(node3);
                trans.AddNewlyCreatedDBObject(node3, true);

                // 获取直线的起点和终点
                Point3d startPoint = originalLine.StartPoint;
                Point3d endPoint = originalLine.EndPoint;

                // 计算向量
                Vector3d lineDirection = (endPoint - startPoint).GetNormal();

                // 计算与圆圈相切的点
                Point3d firstTangentPoint = breakPoint - lineDirection * nodeRadius;
                Point3d secondTangentPoint = breakPoint + lineDirection * nodeRadius;

                // 创建两条新的直线段
                Line lineSegment1 = new Line(startPoint, firstTangentPoint);
                Line lineSegment2 = new Line(secondTangentPoint, endPoint);

                // 复制原直线的属性到新直线段
                lineSegment1.Linetype = lineType;
                lineSegment1.LinetypeScale = lineTypeScale;
                lineSegment1.Color = color;
                lineSegment1.Layer = layer;
                lineSegment1.LineWeight = lineWeight;

                lineSegment2.Linetype = lineType;
                lineSegment2.LinetypeScale = lineTypeScale;
                lineSegment2.Color = color;
                lineSegment2.Layer = layer;
                lineSegment2.LineWeight = lineWeight;

                // 将新线段添加到块表记录中
                btr.AppendEntity(lineSegment1);
                trans.AddNewlyCreatedDBObject(lineSegment1, true);
                btr.AppendEntity(lineSegment2);
                trans.AddNewlyCreatedDBObject(lineSegment2, true);

                // 为新线段添加长度标注
                AddLengthMText(trans, btr, lineSegment1);
                AddLengthMText(trans, btr, lineSegment2);

                // 删除原来的直线
                originalLine.Erase();

                // 提交事务
                trans.Commit();
            }
        }

        private void RemoveLengthMText(Transaction trans, BlockTableRecord btr, Line originalLine)
        {
            // 遍历图形空间中的所有MText对象
            foreach (ObjectId id in btr)
            {
                Entity entity = trans.GetObject(id, OpenMode.ForRead) as Entity;
                if (entity is MText mText)
                {
                    // 检查MText的位置是否在原直线的中点上方
                    Point3d midPoint = new Point3d(
                        (originalLine.StartPoint.X + originalLine.EndPoint.X) / 2,
                        (originalLine.StartPoint.Y + originalLine.EndPoint.Y) / 2,
                        (originalLine.StartPoint.Z + originalLine.EndPoint.Z) / 2
                    );

                    Vector3d offset = new Vector3d(0, 5, 0);
                    Point3d expectedPosition = midPoint + offset;

                    if (ArePointsClose(mText.Location, expectedPosition))
                    {
                        mText.UpgradeOpen();
                        mText.Erase();
                    }
                }
            }
        }

        private bool ArePointsClose(Point3d point1, Point3d point2, double tolerance = 0.001)
        {
            return point1.DistanceTo(point2) <= tolerance;
        }

        private void AddLengthMText(Transaction trans, BlockTableRecord btr, Line lineSegment)
        {
            // 计算线段的中点
            Point3d midPoint = new Point3d(
                (lineSegment.StartPoint.X + lineSegment.EndPoint.X) / 2,
                (lineSegment.StartPoint.Y + lineSegment.EndPoint.Y) / 2,
                (lineSegment.StartPoint.Z + lineSegment.EndPoint.Z) / 2
            );

            // 计算MText的位置（线段上方5个单位）
            Vector3d offset = new Vector3d(0, 5, 0);
            Point3d mTextPosition = midPoint + offset;

            // 创建MText对象来显示长度
            MText mText = new MText
            {
                Location = mTextPosition,
                TextHeight = 2.5,
                Contents = $"{lineSegment.Length:F2}",
                Attachment = AttachmentPoint.MiddleCenter
            };

            btr.AppendEntity(mText);
            trans.AddNewlyCreatedDBObject(mText, true);
        }
        #endregion
    }
}


